﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Lucene.Net.Search;
using Lucene.Net.Index;
using Lucene.Net.Documents;
using Lucene.Net.Store;
using Lucene.Net.Analysis;
using Lucene.Net.Analysis.Standard;
using Version = Lucene.Net.Util.Version;
using Lucene.Net.Util;

namespace Lucene.Net.UnitTest
{
    /// <summary>
    /// UnitTest1 的摘要说明
    /// </summary>
    [TestClass]
    public class UnitTest1
    {
        internal class AnonymousClassCollector : Collector
        {
            #region
            private Scorer scorer;
            private int docBase;

            // simply print docId and score of every matching document
            public override void Collect(int doc)
            {
                //return ("doc=" + doc + docBase + " score=" + scorer.Score());
            }

            public override bool AcceptsDocsOutOfOrder()
            {
                return true;
            }

            public override void SetNextReader(IndexReader reader, int docBase)
            {
                this.docBase = docBase;
            }

            public override void SetScorer(Scorer scorer)
            {
                this.scorer = scorer;
            }
            #endregion
        }

        /// <summary>Use the norms from one field for all fields.  Norms are read into memory,
        /// using a byte of memory per document per searched field.  This can cause
        /// search of large collections with a large number of fields to run out of
        /// memory.  If all of the fields contain only a single token, then the norms
        /// are all identical, then single norm vector may be shared. 
        /// </summary>
        internal class OneNormsReader : FilterIndexReader
        {
            #region
            private System.String field;

            public OneNormsReader(IndexReader in_Renamed, System.String field)
                : base(in_Renamed)
            {
                this.field = field;
            }

            public override byte[] Norms(System.String field)
            {
                return in_Renamed.Norms(this.field);
            }
            #endregion
        }

        public UnitTest1()
        {
            //
            //TODO: 在此处添加构造函数逻辑
            //
        }

        private TestContext testContextInstance;

        /// <summary>
        ///获取或设置测试上下文，该上下文提供
        ///有关当前测试运行及其功能的信息。
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region 附加测试特性
        //
        // 编写测试时，可以使用以下附加特性:
        //
        // 在运行类中的第一个测试之前使用 ClassInitialize 运行代码
        // [ClassInitialize()]
        // public static void MyClassInitialize(TestContext testContext) { }
        //
        // 在类中的所有测试都已运行之后使用 ClassCleanup 运行代码
        // [ClassCleanup()]
        // public static void MyClassCleanup() { }
        //
        // 在运行每个测试之前，使用 TestInitialize 来运行代码
        // [TestInitialize()]
        // public void MyTestInitialize() { }
        //
        // 在每个测试运行完之后，使用 TestCleanup 来运行代码
        // [TestCleanup()]
        // public void MyTestCleanup() { }
        //
        #endregion

        [TestMethod]
        public void TestMethod1()
        {
            //
            // TODO: 在此处添加测试逻辑
            //
            Search();
        }

        public void Search()
        {
            #region
            var indexDir = new System.IO.DirectoryInfo(@"E:\资料\Lucene\Lucene原理与代码分析完整版\indexDir\Data-Product\");
            BooleanQuery queryConditionColl = AnalysisQuery();
            IndexReader reader = IndexReader.Open(FSDirectory.Open(indexDir), true); // only searching, so read-only=true
            Searcher searcher = new IndexSearcher(reader);
            Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_CURRENT);

            DoPagingSearch(searcher, queryConditionColl, 1, 20, false, false);
            reader.Close();

            #endregion
        }

        private BooleanQuery AnalysisQuery()
        {
            #region
            //Query query1 = new TermQuery(new Term(FieldValue, "name1")); // 词语搜索
            //Query query2 = new WildcardQuery(new Term(FieldName, "name*")); // 通配符 
            //Query query3 = new PrefixQuery(new Term(FieldName, "name1")); // 字段搜索 Field:Keyword，自动在结尾添加 *
            //Query query4 = new RangeQuery(new Term(FieldNumber, NumberTools.LongToString(11L)), new Term(FieldNumber, NumberTools.LongToString(13L)), true); // 范围搜索
            //Query query5 = new FilteredQuery(query, filter); // 带过滤条件的搜索

            var minPrice = 10;
            var maxPrice = 0;


            BooleanQuery queryConditionColl = new BooleanQuery();
            var minPriceQuery = NumericRangeQuery.NewDoubleRange("MinPrice", minPrice, maxPrice >= minPrice ? maxPrice : double.MaxValue, true, true);
            queryConditionColl.Add(minPriceQuery, BooleanClause.Occur.MUST);

            if (maxPrice >= minPrice)
            {
                var maxPriceQuery = NumericRangeQuery.NewDoubleRange("MaxPrice", minPrice <= maxPrice ? minPrice : double.MinValue, maxPrice, false, true);
                queryConditionColl.Add(maxPriceQuery, BooleanClause.Occur.MUST);
            }

            return queryConditionColl;
            #endregion
        }

        private static void DoPagingSearch(Searcher searcher, Query query, int currentPageIndex, int hitsPerPage, bool raw, bool interactive)
        {
            #region
            // Collect enough docs to show 5 pages
            TopScoreDocCollector collector = TopScoreDocCollector.create(currentPageIndex * hitsPerPage, false);
            searcher.Search(query, collector);
            ScoreDoc[] hits = collector.TopDocs().scoreDocs;

            int numTotalHits = collector.GetTotalHits();
            var TotalHits = numTotalHits;
            var Index = 0;
            var Count = 0;
            if ((currentPageIndex - 1) * hitsPerPage < numTotalHits)
            {
                Index = (currentPageIndex - 1) * hitsPerPage;
            }
            else
            {
                //searchResult.List.Add("No such page");
            }
            Count = System.Math.Min(numTotalHits, hitsPerPage);

            if (Count > hits.Length)
            {
                #region
                collector = TopScoreDocCollector.create(numTotalHits, false);
                searcher.Search(query, collector);
                hits = collector.TopDocs().scoreDocs;
                #endregion
            }

            Count = System.Math.Min(hits.Length, Index + hitsPerPage);

            for (int i = Index; i < Count; i++)
            {
                #region
                Document doc = searcher.Doc(hits[i].doc);
                string fieldValue = doc.Get("Title");
                if (string.IsNullOrEmpty(fieldValue) == false)
                {
                }
                #endregion
            }
            #endregion
        }
    }
}
